package com.siwei.mes.service.laboratory.impl;

import com.siwei.mes.entity.AssociationStorage;
import com.siwei.mes.entity.ShxhSynchronizedata;
import com.siwei.mes.entity.UploadLaboratoryEntity;
import com.siwei.mes.entity.experiment.Experiment;
import com.siwei.mes.entity.experiment.ExperimentDetail;
import com.siwei.mes.entity.laboratory.ImportList;
import com.siwei.mes.entity.laboratory.PrintReport;
import com.siwei.mes.entity.laboratory.WtConsign;
import com.siwei.mes.entity.laboratory.concrete.SampleUcHnt;
import com.siwei.mes.enums.CheckEnum;
import com.siwei.mes.enums.ExperimentStatusEnum;
import com.siwei.mes.enums.MaterialsEnum;
import com.siwei.mes.mapper.AssociationStorageMapper;
import com.siwei.mes.mapper.ShxhSynchronizedataMapper;
import com.siwei.mes.mapper.experiment.ExperimentDetailMapper;
import com.siwei.mes.mapper.experiment.ExperimentMapper;
import com.siwei.mes.mapper.laboratory.*;
import com.siwei.mes.service.experiment.ExperimentService;
import com.siwei.mes.service.laboratory.DownloadLaboratoryService;
import com.siwei.mes.service.laboratory.factory.concrete.ConcreteLaboratoryFactoryService;
import com.siwei.mes.service.laboratory.factory.material.MaterialLaboratoryFactoryService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.siwei.mes.common.exception.handler.MessageHandler.assertTrue;

/**
 * 上传协会
 *
 * @author chenmaolin
 */
@Service
public class DownloadLaboratoryServiceImpl implements DownloadLaboratoryService {
    private static final Logger log = LoggerFactory.getLogger("laboratory");
    @Resource
    private ExperimentMapper experimentMapper;
    @Resource
    private ExperimentDetailMapper experimentDetailMapper;
    @Resource
    private ShxhSynchronizedataMapper shxhSynchronizedataMapper;
    @Resource
    private WTSampleMapper wtSampleMapper;
    @Resource
    private AssociationStorageMapper associationStorageMapper;
    @Resource
    private PrintReportMapper printReportMapper;
    @Resource
    private DownloadLaboratoryService downloadLaboratory;
    @Resource
    private ImportListMapper importListMapper;
    @Resource
    private ExperimentService experimentService;
    @Resource
    private WTConsignMapper wtConsignMapper;
    @Resource
    private ConcreteLaboratoryFactoryService concreteLaboratoryFactoryService;
    @Resource
    private MaterialLaboratoryFactoryService materialLaboratoryFactoryService;
    @Resource
    private UploadLaboratoryMapper uploadLaboratoryMapper;

    @Override
    public void downloadReportLaboratory(UploadLaboratoryEntity entity) {
        processExperimentIds(entity, false);
    }

    @Override
    public void downloadLaboratory(UploadLaboratoryEntity entity) {
        processExperimentIds(entity, true);
    }

    /**
     * 处理试验委托逻辑
     *
     * @param entity         上传或下载实体
     * @param isFullDownload 是否全量下载
     * @throws Exception 异常
     */
    private void processExperimentIds(UploadLaboratoryEntity entity, boolean isFullDownload) {
        assertTrue(entity == null || entity.getExperimentId() == null || entity.getExperimentId().isEmpty(), "下载上海协会数据，试验台账id不允许为空！");
        List<String> experimentIds = entity.getExperimentId();

        for (String experimentId : experimentIds) {
            try {
                Long id = Long.parseLong(experimentId);
                Experiment experiment = experimentService.loadById(id);
                if (experiment == null || experiment.getCheckType() == null || experiment.getCheckType().equals(CheckEnum.QUICK.getCode())) {
                    log.error("不允许同步快检业务或试验信息为空... 台账id：" + id);
                    continue;
                }

                List<ShxhSynchronizedata> synchronizedata = shxhSynchronizedataMapper.getList(new ShxhSynchronizedata().setExperimentId(id));
                if (synchronizedata == null || synchronizedata.isEmpty() || synchronizedata.get(0).getConsignId() == null) {
                    log.error("此台账未正确同步到协会软件,未查询到协会台账id... 品控台账id：" + id);
                    continue;
                }
                //根据台账id 查询协会台账数据
                String consignId = synchronizedata.get(0).getConsignId();
                Map<String, Object> wtSampleAndConsign = wtSampleMapper.findWTSampleAndWTConsign(consignId);
                if (wtSampleAndConsign == null) {
                    log.error("协会台账数据有误，未查询到协会台账信息... 协会台账id：" + consignId);
                    continue;
                }
                /**更新协会报告信息*/
                this.updateAssociationReportInfo(experiment, wtSampleAndConsign, consignId);

                /**是否全量下载*/
                if (isFullDownload) {
                    this.processFullDownload(experiment, synchronizedata.get(0));
                }
            } catch (NumberFormatException e) {
                log.error("试验台账id格式错误：" + experimentId, e);
            }
        }
    }

    /**
     * 更新协会报告信息
     *
     * @param experiment         试验委托信息
     * @param wtSampleAndConsign 协会样品和协会委托信息
     * @param consignId          协会委托id
     */
    private void updateAssociationReportInfo(Experiment experiment, Map<String, Object> wtSampleAndConsign, String consignId) {
        Long sampleId = getLongValue(wtSampleAndConsign, "SampleID");
        Long specId = getLongValue(wtSampleAndConsign, "Spec_ID");
        Long gradeId = getLongValue(wtSampleAndConsign, "GradeID");
        String reportId = getStringValue(wtSampleAndConsign, "Report_ID");

        List<AssociationStorage> associationStorageList = associationStorageMapper.getList(new AssociationStorage().setExperimentId(experiment.getId()));
        AssociationStorage storage = new AssociationStorage()
                .setExperimentId(experiment.getId())
                .setGradeId(gradeId)
                .setSampleId(sampleId)
                .setSpecId(specId)
                .setReportId(reportId);

        //同步协会报告信息到品控
        if (associationStorageList == null || associationStorageList.isEmpty()) {
            associationStorageMapper.insertSelective(storage);
        } else {
            storage.setId(associationStorageList.get(0).getId());
            associationStorageMapper.updateByPrimaryKeySelective(storage);
        }
        /**这里修改品控试验台账中的试验委托协会报告编号*/
        if (StringUtils.isNotBlank(reportId)) {
            log.info("downloadReportLaboratory修改对应试验委托报告编号，试验台账id：【{}】，试验委托编号：【{}】，报告编号：【{}】", experiment.getId(), experiment.getExperimentNo(), reportId);
            experiment.setReportNo(reportId);
            experiment.setUpdateTime(new Date());
            PrintReport printReport = printReportMapper.queryByConSignID(consignId);
            if (printReport != null) {
                experiment.setReportDate(printReport.getReportAuditTime());
            }
            experimentMapper.updateByPrimaryKeySelective(experiment);
            //同步修改多consignId 的实验
            if (shxhSynchronizedataMapper.countByConsignId(consignId) > 1) {
                experiment.setConsignId(consignId);
                experimentMapper.updateBatchReportByConsignId(experiment);
            }
        }
    }

    /**
     * 处理下载逻辑
     *
     * @param experiment      试验委托信息
     * @param synchronizedata 协会台账信息
     */
    private void processFullDownload(Experiment experiment, ShxhSynchronizedata synchronizedata) {
        String sampleNo = synchronizedata.getSampleId();
        if (StringUtils.isBlank(sampleNo)) {
            return;
        }
        /**查询试验委托详情信息*/
        List<ExperimentDetail> experimentDetailList = experimentDetailMapper.getList(new ExperimentDetail().setExperimentId(experiment.getId()));

        /**查询协会是否存在实验台帐报表信息  不存在直接下载*/
        PrintReport printReport = printReportMapper.queryByConSignID(synchronizedata.getConsignId());
        if (printReport != null) {
            experiment.setReportNo(printReport.getReportID());
            experiment.setReportDate(printReport.getReportAuditTime());

            List<String> stringList = new ArrayList<>();
            stringList.add(experiment.getId().toString());
            UploadLaboratoryEntity UploadLaboratoryEntity = new UploadLaboratoryEntity()
                    .setExptId(experiment.getId())
                    .setExperimentId(stringList);
            downloadLaboratory.downloadReportLaboratory(UploadLaboratoryEntity);
        }

        /**查询协会委托状态*/
        Map<String, Object> wtSampleList = wtSampleMapper.findWTSampleList(sampleNo);
        if (wtSampleList == null) {
            log.error("协会台账数据有误，未查询到协会台账信息... 协会样品id：" + sampleNo + "品控台账编号：" + experiment.getExperimentNo());
            throw new RuntimeException("协会台账数据有误，未查询到协会台账信息... 协会样品id：" + sampleNo + "品控台账编号：" + experiment.getExperimentNo());
        }

        /**如果协会委托为1 已完成*/
        if (wtSampleList.get("Sample_Status") != null && "1".equals(wtSampleList.get("Sample_Status").toString()) && StringUtils.isNotBlank(synchronizedata.getConsignId())) {
            experiment.setExperimentStatus(ExperimentStatusEnum.FINISH.getCode());
        }

        //是否合格
        if (wtSampleList.get("Sample_Regular") != null) {
            if ("true".equals(wtSampleList.get("Sample_Regular").toString())) {
                experiment.setIsQualified(1);
            } else if ("false".equals(wtSampleList.get("Sample_Regular").toString())) {
                experiment.setIsQualified(0);
            }
        }

        //代表数量
        if (wtSampleList.get("Delegate_Quan") != null) {
            experiment.setBehalfNumber(Double.parseDouble(wtSampleList.get("Delegate_Quan").toString()));
        }


        List<WtConsign> wtConsign = wtConsignMapper.findWTConsignListBysampleId(sampleNo);
        if (wtConsign != null && wtConsign.size() > 0 && wtConsign.get(0).getExamConclusion() != null) {
            experiment.setConclusion(wtConsign.get(0).getExamConclusion());
        }


        //委托时间
        SampleUcHnt sampleUCHNTBySampleId = uploadLaboratoryMapper.findSampleUCHNTBySampleId(sampleNo);
        if (sampleUCHNTBySampleId != null && sampleUCHNTBySampleId.getZhiZuoRiQi() != null) {
            experiment.setEntrustTime(sampleUCHNTBySampleId.getZhiZuoRiQi());
        }

        if (MaterialsEnum.CONCRETE.getCode().equals(experiment.getExperimentType())) {
            /**更新品控委托*/
            experimentMapper.updateByPrimaryKeySelective(experiment);
            /**处理下载*/
            concreteLaboratoryFactoryService.processDownload(sampleNo, experimentDetailList, experiment, wtSampleList);
        } else {
            /**根据进料id查询进料数据*/
            List<String> importIdList = new ArrayList<>();
            importIdList.add(synchronizedata.getImportId());
            List<ImportList> importList = importListMapper.findImportListById(importIdList);
            if (importList == null || importList.isEmpty() || StringUtils.isBlank(importList.get(0).getSampleID())) {
                log.error("根据进料id未查询到进料数据/进料规格为空！进料id : " + synchronizedata.getImportId());
                throw new RuntimeException("根据进料id未查询到进料数据/进料规格为空！进料id : " + synchronizedata.getImportId());
            }
            String samId = importList.get(0).getSampleID();

            if (StringUtils.isNotBlank(importList.get(0).getGroupId())) {
                experiment.setBatchNumber(importList.get(0).getGroupId());
            }
            /**更新品控委托*/
            experimentMapper.updateByPrimaryKeySelective(experiment);
            /**处理下载*/
            materialLaboratoryFactoryService.processDownload(sampleNo, experimentDetailList, experiment, wtSampleList, samId);
        }
    }

    /**
     * 获取map值 返回long
     *
     * @param map
     * @param key
     * @return
     */
    private Long getLongValue(Map<String, Object> map, String key) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        if (!map.containsKey(key)) {
            return null;
        }
        Object value = map.get(key);
        return value != null ? Long.parseLong(value.toString()) : null;
    }

    /**
     * 获取map值 返回String
     *
     * @param map
     * @param key
     */
    private String getStringValue(Map<String, Object> map, String key) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        if (!map.containsKey(key)) {
            return null;
        }
        Object value = map.get(key);
        return value != null ? value.toString() : null;
    }
}